plinstrument:
{
calc:"
// (based on V-SHOW X760)

#include	colorconv
#include	colortable
#include	ledref
#include	o_pan
#include	o_tilt
#include	o_shutter
#include	o_dimmer
#include	o_color
#include	o_pix
#include	o_zoom


// controls
cMod;
cPan; cTlt; cSpd; cZom; cRot; cRst; cDim; cSht; cBSh; cPix; cBPx; cFSl; cFSp; cBSl; cBSp; cCol; cCtc; cBDm;


// parameters
pRPn;
pRTl;
pMod;
pDmr;

// constants
kPosY = 0.000;
kDia = 0.15;
kBaseWid = 0.26;
kBaseHi  = 0.11;
kBaseDep = 0.21;
kArmDep  = 0.09;
kArmWid  = 0.31;
kCenterHi = 0.33;
kZBack  =  0.135;
kZFront = -0.134;
kHeadWid = 0.23;
kHeadHi  = 0.24;

kSource = LEDRefConv(7 * 60, kDia, kLEDRefWatt_RGBW, kLEDRefDia_RGBW, kLEDRefSrc_RGBW);
kWhite = kLEDRefWhite_RGBW;
kBSource = LEDRefConv(28 * 0.5, kDia, kLEDRefWatt_RGB, kLEDRefDia_RGB, kLEDRefSrc_RGB);


// protocol parameters
CENTER[1] = kCenterHi;
PAN;
TILT;
LIGHT;
SHAPE;
CTLS;

PRM=1;
CTL;


// pan, tilt

gPan  = PanNew(540);
gTilt = TiltNew(205);

PanTiltTime#
(
	s = cSpd / 255;
	PanSetInv(gPan,   pRPn);
	TiltSetInv(gTilt, pRTl);
	PanSetSpeedN(gPan, s);
	TiltSetSpeedN(gTilt, s);
	c  = PanPos(gPan, $0, cPan / 256);
	c += TiltPos(gTilt, $0, cTlt / 256);
	c
);


// shutter

ShutterTimeO#	// (time, obj, ctl)
(
	so = $1;
	sc = $2;

	(sc < 6)?	// open
	(
		ShutterOpen(so);
	)
	:(sc < 56)?	// strobe
	(
		ShutterStrobe(so, $0, CtlN(6, 55, sc));
	)
	:(sc < 106)?	// pulse
	(
		ShutterPulse(so, $0, CtlN(56, 105, sc));
	)
	:(sc < 156)?	// random
	(
		ShutterStrobeRandom(so, $0, ParamLin(0.25, 0.75, 106, 155, sc));
	)
	:(sc < 206)?	// closing
	(
		ShutterClosing(so, $0, CtlN(156, 205, sc));
	)
	:				// opening
	(
		ShutterOpening(so, $0, CtlN(206, 255, sc));
	);
);

gShutter = ShutterNew(1, 25, 1 / 30);	// (?)

ShutterTime#
(
	ShutterTimeO($0, gShutter, cSht);
);


// dimmer

gDimmer = DimmerNew();

DimmerTime#
(
	DimmerSetCurve(gDimmer, pDmr);
	r = (pMod == 0)? 256 : 255;
	DimmerLev(gDimmer, $0, cDim / r);
);


// color
kColors = 42;

COLMAC#	// (r, g, b, w) rgbw
(
	Vec($0 / 255, $1 / 255, $2 / 255, $3 / 255)
);

kColorTbl = Vec(
COLMAC(000, 255, 255, 000),
COLMAC(255, 255, 000, 000),
COLMAC(255, 000, 255, 000),
COLMAC(156, 126, 000, 000),
COLMAC(152, 115, 009, 000),
COLMAC(198, 114, 009, 000),
COLMAC(255, 056, 000, 000),
COLMAC(255, 135, 000, 000),
COLMAC(255, 100, 000, 000),
COLMAC(255, 065, 000, 000),
COLMAC(255, 083, 002, 000),
COLMAC(255, 112, 000, 141),
COLMAC(255, 087, 000, 107),
COLMAC(255, 107, 000, 130),
COLMAC(243, 117, 039, 197),
COLMAC(000, 255, 135, 000),
COLMAC(000, 194, 130, 000),
COLMAC(041, 219, 000, 000),
COLMAC(245, 202, 000, 000),
COLMAC(237, 163, 000, 000),
COLMAC(230, 160, 000, 069),
COLMAC(255, 166, 000, 000),
COLMAC(255, 122, 000, 000),
COLMAC(255, 141, 031, 000),
COLMAC(217, 130, 028, 000),
COLMAC(255, 109, 033, 000),
COLMAC(255, 020, 015, 000),
COLMAC(051, 255, 051, 000),
COLMAC(206, 255, 056, 000),
COLMAC(074, 255, 082, 000),
COLMAC(000, 186, 255, 000),
COLMAC(206, 255, 000, 000),
COLMAC(084, 255, 013, 000),
COLMAC(227, 041, 056, 000),
COLMAC(255, 058, 000, 000),
COLMAC(255, 197, 061, 000),
COLMAC(077, 255, 000, 000),
COLMAC(000, 255, 087, 000),
COLMAC(255, 143, 013, 000),
COLMAC(253, 171, 026, 000),
COLMAC(222, 084, 000, 000),
COLMAC(255, 046, 002, 000));


kPixs = 7;
gPixs = PixNew(kPixs);
gColorM = ColorNew(kColors);
ColorSetSpeed(gColorM, 0.5 / kColors, 5 / kColors);	// (?)
ColorSetZeroTime(gColorM, 1);	// (?)

PixC#	// (pix) rgbw
(
	p = cPix[$0];
	Vec(p.cR / 255, p.cG / 255, p.cB / 255, p.cW / 255)
);

ColorTime#
(
	(cCol < 46)?	// no macro
	(
		Any(pMod, 0, 2)?	// single color
		(
			c = PixC(0);
		);
	)
	:	// macro
	(
		c = kColorTbl[floor((cCol - 46) / 5)];
	);
	PixSetAll(gPixs, c);

	Any(pMod, 1, 3)?	// per pixel htp (?)
	(
		@(i < kPixs)
		(
			c = PixC(i);
			PixHtp(gPixs, i, c);
			++i;
		);
	);
);


// ctc

CTC#
(
CTFilter(6500, $0)
);

kOpen = Vec(1, 1, 1);
kCtcTbl = Vec(
CTC(8000),
CTC(7500),
CTC(6500),
CTC(6000),
CTC(5600),
CTC(5000),
CTC(4500),
CTC(4000),
CTC(3500),
CTC(3200),
CTC(3000),
CTC(2700),
CTC(2500),
CTC(2000));

gCtc;	// rgb

CtcTime#
(
	(cCtc < 18)?
	(
		gCtc = kOpen;
	)
	:
	(
		gCtc  = kCtcTbl[floor((cCtc - 18) / 17)];
	);
);


// zoom

gZoom = ZoomNew();

ZoomTime#
(
	ZoomPos(gZoom, $0, cZom / 256);
);


// backlight shutter

gBShutter = ShutterNew(1, 25, 1 / 30);	// (?)

BShutterTime#
(
	ShutterTimeO($0, gBShutter, cBSh);
);


// backlight dimmer

gBDimmer = DimmerNew();

BDimmerTime#
(
	DimmerSetCurve(gBDimmer, pDmr);

	(pMod == 0)?
	(
		DimmerLev(gBDimmer, $0, 1);
	)
	:
	(
		r = (pMod == 1)? 256 : 255;
		DimmerLev(gBDimmer, $0, cBDm / r);
	);
);


// backlight color
kBPixs = 28;

gBPixs = PixNew(kBPixs);

BPixC#	// (pix) rgb
(
	p = cBPx[$0];
	Vec(p.cR / 255, p.cG / 255, p.cB / 255)
);

BColorTime#
(
	(pMod < 2)?		// single color
	(
		c = BPixC(0);
		PixSetAll(gBPixs, c);
	)
	:
	(
		@(i < kBPixs)
		(
			c = BPixC(i);
			PixSet(gBPixs, i, c);
			++i;
		);
	);
);


// protocol methods

UPDATE#
(
	dir = PanTiltTime($0);
	ShutterTime($0);
	DimmerTime($0);
	ColorTime($0);
	CtcTime($0);
	ZoomTime($0);

	BShutterTime($0);
	BDimmerTime($0);
	BColorTime($0);

	PRM?
	(
		cMod = pMod;
		CTLS = 1;

		// setup light
		l = LIGHT[0];
		l.pos[1] = kPosY;
		l.pos[2] = kZFront;
		l.dia = kDia;
		LIGHT[0] = l;
	);

	(dir | PRM)?
	(
		PAN = gPan.cur;
		TILT = 90 + gTilt.cur;
		SHAPE = MovingShape(kBaseWid, kBaseHi, kHeadWid, kHeadHi, kZFront, kZBack, kCenterHi, PAN, TILT, kBaseDep, kArmDep, kArmWid);
	);

	(
		fa = ParamLin(3.15, 45, 0, 1, gZoom.cur);	// field angle(?)
		cent = ParamLin(0, 2, 0, 1, gZoom.cur);
		spread = Spread(cent, 0.1, fa);
		
		// main light
		c0 = PixAverage(gPixs);
		c0 = RGBfromRGBW(c0, kWhite);
		c0 = VecMul(c0, gCtc);
		c0 = VecScale(c0, kSource * gDimmer.cur * gShutter.cur);
		
		// back light
		c1 = PixAverage(gBPixs);
	//	c1 = VecMul(c1, gBCtc);
		c1 = VecScale(c1, kBSource * gBDimmer.cur * gBShutter.cur);

		// setup light
		l = LIGHT[0];
		l.color = VecAdd(c0, c1);
		l.spdh = spread;
		l.spdv = spread;
		l.cnt = cent;
		LIGHT[0] = l;
	);

	PRM = CTL = 0;
);

";


chmap:
"cPan.w cTlt.w cSpd cZom.w cRot cRst cDim.w cSht cBSh cPix(cR cG cB cW)[1] cBPx(cR cG cB)[1] cFSl cFSp cBSl cBSp cCol cCtc",
"cPan.w cTlt.w cSpd cZom.w cRot cRst cBDm.w cBSh cBPx(cR cG cB)[1] cBSl cBSp cDim cSht cCol cCtc cPix(cR cG cB cW)[7]",
"cPan.w cTlt.w cSpd cZom.w cRot cRst cDim   cSht cPix(cR cG cB cW)[1] cFSl cFSp cCol cCtc cBDm cBSh cBPx(cR cG cB)[28]",
"cPan.w cTlt.w cSpd cZom.w cRot cRst cDim   cSht cCol cCtc cPix(cR cG cB cW)[7] cBDm cBSh cBPx(cR cG cB)[28]";


ctlprop:
{
	ctls:
	{
		id:cRot;
		name:Rotate;
	},
	{
		id:cBSh;
		name:Bk Shutter;
	},
	{
		id:cBDm;
		name:Bk Dimmer;
		ini:255;
	},
	{
		id:cBR;
		name:Bk R;
		ini:255;
	},
	{
		id:cBG;
		name:Bk G;
		ini:255;
	},
	{
		id:cBB;
		name:Bk B;
		ini:255;
	},
	{
		id:cCtc;
		name:CTC;
	},
	{
		id:cBPxs;
		label:Bk Pix;
		base:8;
	},
	{
		id:cFSl;
		name:FX Select;
	},
	{
		id:cFSp;
		name:FX Speed;
	},
	{
		id:cBSl;
		name:BkFX Select;
	},
	{
		id:cBSp;
		name:BkFX Speed;
	};
};


prm:
{
	controls:
	{
		type:check;
		id:pRPn;
		name:"-Pan";
	},
	{
		type:check;
		id:pRTl;
		name:"-Tilt";
	},
	{
		type:selector;
		id:pMod;
		name:Mode;
		ini:0;
		items:
		{
			text:26ch;
			value:0;
		},
		{
			text:49ch;
			value:1;
		},
		{
			text:105ch;
			value:2;
		},
		{
			text:127ch;
			value:3;
		};
	},
	{
		type:selector;
		id:pDmr;
		name:Dimmer;
		ini:0;
		items:
		{
			text:Linear;
			value:0;
		},
		{
			text:SqLaw;
			value:1;
		},
		{
			text:ISqLaw;
			value:2;
		},
		{
			text:S Curve;
			value:3;
		};
	};
};

};
